/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.yuecai.modules.yc_user.service.impl;

import com.yuecai.exception.BadRequestException;
import com.yuecai.exception.EntityExistException;
import com.yuecai.modules.yc_order.service.utils.MakeOrderNum;
import com.yuecai.modules.yc_real_name.domain.YcRealName;
import com.yuecai.modules.yc_real_name.service.YcRealNameService;
import com.yuecai.modules.yc_user.domain.YcUser;
import com.yuecai.modules.yc_user.repository.YcUserRepository;
import com.yuecai.modules.yc_user.service.YcUserService;
import com.yuecai.modules.yc_user.service.dto.UserUpdateDto;
import com.yuecai.modules.yc_user.service.dto.YcUserDto;
import com.yuecai.modules.yc_user.service.dto.YcUserQueryCriteria;
import com.yuecai.modules.yc_user.service.dto.YcUserRegisterDto;
import com.yuecai.modules.yc_user.service.mapstruct.YcUserMapper;
import com.yuecai.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author dm
* @date 2020-06-22
**/
@Service
@RequiredArgsConstructor
public class YcUserServiceImpl implements YcUserService {

    @Autowired
    private  YcUserRepository ycUserRepository;
    @Autowired
    private  YcUserMapper ycUserMapper;
    @Autowired
    private  PasswordEncoder passwordEncoder;
    @Autowired
    private  YcRealNameService ycRealNameService;

    @Override
    public Map<String,Object> queryAll(YcUserQueryCriteria criteria, Pageable pageable){
        Page<YcUser> page = ycUserRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(ycUserMapper::toDto));
    }

    @Override
    public List<YcUserDto> queryAll(YcUserQueryCriteria criteria){
        return ycUserMapper.toDto(ycUserRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public YcUserDto findById(Long id) {
        Optional<YcUser> byId = ycUserRepository.findById(id);
        if (byId.isPresent()){
            return ycUserMapper.toDto(byId.get());
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public YcUserDto create(YcUser resources) {
        if(ycUserRepository.findByPhone(resources.getPhone()) != null){
            throw new EntityExistException(YcUser.class,"phone",resources.getPhone());
        }
        return ycUserMapper.toDto(ycUserRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(YcUser resources) {
        YcUser ycUser = ycUserRepository.findById(resources.getId()).orElseGet(YcUser::new);
        ValidationUtil.isNull( ycUser.getId(),"YcUser","id",resources.getId());
        YcUser ycUser1 = ycUserRepository.findByPhone(resources.getPhone());
        if(ycUser1 != null && !ycUser1.getId().equals(ycUser.getId())){
            throw new EntityExistException(YcUser.class,"phone",resources.getPhone());
        }
        ycUser.copy(resources);
        ycUserRepository.save(ycUser);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            ycUserRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<YcUserDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YcUserDto ycUser : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("用户名", ycUser.getUsername());
            map.put("密码", ycUser.getPassword());
            map.put("手机号", ycUser.getPhone());
            map.put("头像地址", ycUser.getImgUrl());
            map.put("推荐人Id", ycUser.getPid());
            map.put("0正常1删除2冻结", ycUser.getState());
            map.put("创建时间", ycUser.getCreateTime());
            map.put("修改时间", ycUser.getLastUpdateTime());
            map.put("昵称", ycUser.getNickName());
            map.put("0女1男", ycUser.getSex());
            map.put("生日", ycUser.getBirthday());
            map.put("城市", ycUser.getCity());
            map.put("职业", ycUser.getOccupation());
            map.put("个签", ycUser.getSign());
            map.put("上次登陆时间", ycUser.getLastLoginTime());
            map.put("用户等级 type为1的时候有值 1普通用户、2会员用户", ycUser.getLevel());
            map.put("1店铺用户、2司机、3业务员", ycUser.getType());
            map.put("是否实名，1实名了，0未实名", ycUser.isRealName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public YcUser findByName(String phone) {
        YcUser user = null;
        if (isMobileNO(phone)){
            Long aLong = Long.valueOf(phone);
            Optional<YcUser> byId = ycUserRepository.findById(aLong);
            if (byId.isPresent()){
                user = byId.get();
            }
        }else {
            user = ycUserRepository.findByPhone(phone);
        }
        return user;
    }

    @Override
    @Transactional
    public YcUserDto register(YcUserRegisterDto dto) throws Exception {
        String pid = dto.getPid();
        Optional<YcUser> byIdAndType = ycUserRepository.findByReferralCode(pid);
        if (byIdAndType.isPresent()){
            YcUser user = byIdAndType.get();
            Integer type = user.getType();
            if (type!=3){
                throw new BadRequestException("该业务员不存在！");
            }
            YcUser ycUser = new YcUser();
            BeanUtils.copyProperties(dto,ycUser);
            String encode = passwordEncoder.encode(dto.getPassword());
            ycUser.setPassword(encode);
            ycUser.setReferralCode(MakeOrderNum.referralCode());
            YcUser save = ycUserRepository.save(ycUser);

            YcRealName ycRealName = dto.getYcRealName();
            if (ycRealName!=null){
                ycRealName.setUserId(save.getId());
                ycRealNameService.create(ycRealName);
            }else if (dto.isRealName()){
                throw new Exception("实名信息不能为空");
            }
            return ycUserMapper.toDto(save);
        }
       throw new BadRequestException("推荐人不存在！");
    }

    @Override
    @Transactional
    public YcUserDto putUser(UserUpdateDto dto) {
        YcUser ycUser = new YcUser();
        BeanUtils.copyProperties(dto,ycUser);
        YcUser save = ycUserRepository.save(ycUser);
        return ycUserMapper.toDto(save);
    }

    @Override
    public void sensitiveNformation(HashMap<String, String> map) throws Exception {
        String currentUsername = SecurityUtils.getCurrentUsername();
        Long aLong = Long.valueOf(currentUsername);
        Optional<YcUser> byId = ycUserRepository.findById(aLong);
        if (byId.isPresent()){
            YcUser ycUser = byId.get();
            if (map.containsKey("password")){
                if (map.containsKey("oldPassword")){
                    String password = ycUser.getPassword();
                    boolean oldPassword = passwordEncoder.matches(map.get("oldPassword"), password);
                    if (!oldPassword){
                        throw new Exception("老密码不正确！");
                    }
                }else {
                    throw new Exception("修改密码需要传老密码！");
                }
                ycUser.setPassword(map.get(passwordEncoder.encode(map.get("password"))));
            }else if (map.containsKey("phone")){
                ycUser.setPhone(map.get(map));
            }
        }
        throw new Exception("用户不存在！");
    }

    public static void main(String[] args) {
        if (isMobileNO("16688188456")){
            System.out.println("-----------------");
        }else {
            System.out.println("111111111");
        }
    }
    public static boolean isMobileNO(String mobiles){
        Pattern p = Pattern.compile("^((13[0-9])|(14[0|5|6|7|9])|(15[0-3])|(15[5-9])|(16[6|7])|(17[2|3|5|6|7|8])|(18[0-9])|(19[1|8|9]))\\d{8}$");
        Matcher m = p.matcher(mobiles);
        return !m.matches();
    }

}